﻿using System;
using System.Collections.Generic;
using System.Text;
using KeaoBase;
using System.Reflection;
using System.Threading;
using System.Net.Sockets;
using System.Net;

namespace KeaoDeviceService
{
    public class KeaoDevice
    {
        ~KeaoDevice()
        {
            if (t != null)
            {
                t.Abort();
            }
            if (m_Weight != null)
            {
                m_Weight.CloseDevice();
            }
        }

        private BaseWeight m_Weight;
        private byte[] sendBytes = new byte[5];
        private Thread t;
        private Socket m_ListenSocket;
        private List<Socket> m_CurrentSocket = new List<Socket>();
        private byte[] m_receiveBytes = new byte[1024];

        private void SendWeightNum()
        {
            while (true)
            {
                try
                {
                    Thread.Sleep(500);
                    BitConverter.GetBytes(m_Weight.GetWeightNum()).CopyTo(sendBytes, 0);
                    if (m_Weight._StableStatus)
                    {
                        sendBytes[4] = 0x02;
                    }
                    else
                    {
                        sendBytes[4] = 0x01;
                    }

                    if (m_CurrentSocket.Count > 0)
                    {
                        for (int i = 0; i < m_CurrentSocket.Count; i++)
                        {
                            try
                            {
                                m_CurrentSocket[i].Send(sendBytes);
                            }
                            catch
                            {
                                m_CurrentSocket.RemoveAt(i);
                                i--;
                            }
                        }
                    }
                    else
                    {
                        m_Weight.SetShowNumber(m_Weight.GetWeightNum().ToString());
                    }
                }
                catch (ThreadAbortException)
                {
                    return;
                }
                catch (Exception)
                {
                    continue;
                }

            }
        }

        public bool InitDevice()
        {
            try
            {
                if (KeaoUtils.ConfigGetNodeAttr("称重设备", "状态") == "启用")
                {
                    m_Weight = Assembly.LoadFrom("KeaoWeight.dll").CreateInstance(string.Format("KeaoWeight.{0}", KeaoUtils.ConfigGetNodeAttr("称重设备", "类型"))) as BaseWeight;
                    bool initResult = m_Weight.ConnectDevice(KeaoUtils.ConfigGetNodeAttr("称重设备", "地址"), int.Parse(KeaoUtils.ConfigGetNodeAttr("称重设备", "波特率")), KeaoUtils.GetSplitChar(KeaoUtils.ConfigGetNodeAttr("称重设备", "间隔标识")));
                    if (initResult && KeaoUtils.ConfigGetNodeAttr("显示设备", "状态") == "启用")
                    {
                        initResult = m_Weight.InitShowDevice(KeaoUtils.ConfigGetNodeAttr("显示设备", "地址"));
                    }
                    return initResult;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception err)
            {
                KeaoUtils.LogTxt(string.Format("初始化称重设备异常。{0}", err.Message));
                return false;
            }
        }

        public void InitSocket()
        {
            try
            {
                m_ListenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                m_ListenSocket.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8888));
                m_ListenSocket.Listen(0);
                m_ListenSocket.BeginAccept(OnAcceptSocket, m_ListenSocket);

                t = new Thread(new ThreadStart(SendWeightNum));
                t.Start();
            }
            catch (Exception err)
            {
                KeaoUtils.LogTxt(string.Format("初始化socket异常。{0}", err.Message));
            }
        }

        private void OnAcceptSocket(IAsyncResult Args)
        {
            try
            {
                Socket currentSocket = m_ListenSocket.EndAccept(Args);//收到连接
                currentSocket.BeginReceive(m_receiveBytes, 0, m_receiveBytes.Length, SocketFlags.None, OnReceiveData, currentSocket);
                m_CurrentSocket.Add(currentSocket);
                m_ListenSocket.BeginAccept(OnAcceptSocket, m_ListenSocket);
            }
            catch (Exception err)
            {
                KeaoUtils.LogTxt(string.Format("socket接受连接异常。{0}", err.Message));
            }
        }

        private void OnReceiveData(IAsyncResult Args)
        {
            try
            {
                Socket currentSocket = Args.AsyncState as Socket;
                int i = currentSocket.EndReceive(Args);
                if (i == 0)
                {
                    currentSocket.Close();
                    return;
                }
                string readStr = Encoding.Default.GetString(m_receiveBytes, 0, i);
                if (KeaoUtils.isNumber(readStr))
                {
                    m_Weight.SetShowNumber(readStr);
                }
                while (true)
                {
                    i = currentSocket.Receive(m_receiveBytes, m_receiveBytes.Length, SocketFlags.None);
                    if (i == 0)
                    {
                        currentSocket.Close();
                        break;
                    }
                    readStr = Encoding.Default.GetString(m_receiveBytes, 0, i);
                    if (KeaoUtils.isNumber(readStr))
                    {
                        m_Weight.SetShowNumber(readStr);
                    }
                }
            }
            catch (SocketException)
            {
                return;
            }
            catch (Exception err)
            {
                KeaoUtils.LogTxt(string.Format("socket接受数据异常。{0}", err.Message));
            }
        }
    }
}
